package org.eden.karb.activity.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eden.karb.activity.AudioMonitorService;
import org.eden.karb.activity.EventAnalyser;
import org.eden.karb.common.util.AudioUtils;
import org.eden.karb.event.impl.AudioMonitorEvent;
import org.eden.karb.persistence.dao.SessionDAO;
import org.eden.karb.persistence.entity.Session;
import org.jthompson.monsoon.annotations.Event;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.NoResultException;

/**
 * {@inheritDoc}
 */
public class AudioMonitorServiceImpl implements AudioMonitorService {

    protected Log log = LogFactory.getLog(AudioMonitorServiceImpl.class);

    @Resource
    private SessionDAO sessionDAO;

    @Resource
    private EventAnalyser<AudioMonitorEvent> eventAnalyzer;

    @Event(name = "audioMonitor", type = Event.EventType.LISTENER)
    @Transactional(readOnly = false)
    public void onEvent(AudioMonitorEvent event) {

        if (event != null) {

            if (log.isDebugEnabled()) {
                log.debug("[" + event.getSessionId() + "] processing event " + event.toString());
            }

            persistEvent(event);

            eventAnalyzer.process(event);

            //AudioUtils.printStream(audioLevels);
        }
    }

    private void persistEvent(AudioMonitorEvent event) {
        Session session;
        try {
            session = sessionDAO.findByKey(event.getSessionId().toString());

            if (log.isDebugEnabled()) {
                log.debug("[" + event.getSessionId() + "] updating existing session");
            }

            int[] oldBuffer = AudioUtils.convert(session.getMonitorData());
            int[] newBuffer = event.getLevels();
            int[] updatedBuffer = appendAudioBuffer(oldBuffer, newBuffer);
            session.setMonitorData(updatedBuffer);
            sessionDAO.merge(session);
        } catch (NoResultException e) {

            if (log.isDebugEnabled()) {
                log.debug("[" + event.getSessionId() + "] creating new session");
            }

            session = new Session();
            session.setKey(event.getSessionId().toString());
            session.setMonitorData(event.getLevels());
            sessionDAO.persist(session);

        }
    }

    private int[] appendAudioBuffer(int[] oldBuffer, int[] newBuffer) {
        int[] updatedBuffer = new int[oldBuffer.length + newBuffer.length];
        for (int i = 0, j = 0; i < updatedBuffer.length; i++) {
            if (i < oldBuffer.length) {
                updatedBuffer[i] = oldBuffer[i];
            } else {
                updatedBuffer[i] = newBuffer[j];
                j++;
            }
        }
        return updatedBuffer;
    }
}
